#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>
#include <QString>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTimer>
#include <QDateTime>

#include <QUdpSocket>
#include <QHostAddress>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QNetworkInterface>

struct PositionData {   //定义结构体，用于临时保存数据
    double longitude;   // 经度
    double latitude;    // 纬度
    QDateTime timestamp;// 接收时间戳
    enum Source { Serial, Network } source; // 标记位：区分串口（Serial）/网口（Network）数据
};

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_checkBox_SendInTime_clicked(bool checked);

    /*网络调试助手*/
    void New_Connect();                                            // TCP网口连接
    void Net_readyToRead_TCP();                                    // TCP网口接收
    void Net_readyToRead_UDP();                                    // UDP网口接收
    void Network_To_Serial(const PositionData &data);              // 网口数据转发到串口
    void on_pushButton_NetSend_clicked();                          // TCP与UDP网口发送
    void on_pushButton_Close_Or_Open_Listen_clicked(bool checked); // TCP与UDP网口开关
    void reflash_IP_Port();                                        // 刷新可用IP地址
    void on_pushButton_ClearNet_clicked();                         // 清空网口位置信息
    void stateChanged_Handler(QAbstractSocket::SocketState);       // 网口状态转换提示(待完善)
    void on_pushButton_DisconnectClient_clicked();                 // 主动断开客户端
    void ClientDisconnected();                                     // 客户端断开时更新comboBox_Client

    /*串口调试助手*/
    void Serial_readyToRead();                                     // 串口接收
    void on_pushButton_SerialSend_clicked();                       // 串口发送
    void on_pushButton_Close_Or_Open_Serial_clicked(bool checked); // 串口开关
    void refresh_SerialPorts();                                    // 刷新可用串口号
    void on_pushButton_ClearSerial_clicked();                      // 清空串口位置信息

    PositionData  DataPacket_parsing(const QString& reMessage);// 解包函数：将数据包拆解并返回经纬度数据
    QByteArray packBinaryData(double lon, double lat);         // 组包函数：按题目格式生成二进制数据并返回
    void sendTcpData(const QByteArray& data);                  // 发送函数：接收二进制数据并通过TCP发送至客户端
    void on_pushButton_SaveLocation_clicked();                 // 保存位置信息至指定路径的txt文件中
    void Update_labelTime();                                   // 获取当前时间

private:
    Ui::Widget *ui;

    // 用于设置串口信息
    QSerialPort *serialPort;
    // 用于保存串口号
    QString SerialNum;

    // 用于实现定时发送功能的定时器
    QTimer* timer;
    // 用于刷新当前时间功能的定时器
    QTimer* nowTime;

    // 用于创建一个网络服务端
    QTcpServer* tcpServer;
    QUdpSocket* udpSocket;

    // 用于缓存串口和网口通用的经纬度数据
    QList<PositionData> positionCache;
    // 用 map 关联客户端标识与对应的 socket
    QMap<QString, QTcpSocket*> clientMap;

    // 经纬度
    double longitude;
    double latitude;

    // 获取远程主机的地址和端口
    bool parseHostAddress(const QString& input, QHostAddress& address, quint16& port);
};
#endif // WIDGET_H
